package com.ruoyi.common.utils;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.TimeZone;

/**
 * @author: tianwei
 * @date: 2024-11-26 09:36:32
 * @description: TODO
 */
public class ByteUtils {

    private static final long DAYS_FROM_1970_TO_2000 = 10957; // 从1970年1月1日到2000年1月1日的天数
    private static final long MILLISECONDS_PER_DAY = 86400000; // 一天的毫秒数
    private static final long MILLISECONDS_PER_TENTH_SECOND = 100; // 0.1毫秒

    public static void main(String[] args) throws DecoderException {

        String data = "01C91B0000000111280101102801061000330C0000000000882363F853271800C72263F85327C4EB6200000000002CBF05129B0B0100F41A";
        byte[] bytes = Hex.decodeHex(data);
        ByteBuf byteBuf = Unpooled.wrappedBuffer(bytes);
        byte version = byteBuf.readByte(); //版本
        String TID = String.format("%08X", byteBuf.readIntLE()); //目标标志
        String SID = String.format("%08X", byteBuf.readIntLE()); //信源地址
        String DID = String.format("%08X", byteBuf.readIntLE()); //新宿地址
        String BID = String.format("%08X", byteBuf.readIntLE()); //信息标志
        int NO = byteBuf.readIntLE();    //包序号
        String s = readLittleEndianBytesAsHex(byteBuf, 3); //保留

//        short i = byteBuf.readShortLE();  //时间

//        int i1 = byteBuf.readIntLE();     //日期

        String time = convertToDateTime(byteBuf); //时间
        short dataLen = byteBuf.readShortLE();

        String result = readRemainingAsHexString(byteBuf);
        //C72263F85327C4EB6200000000002CBF05129B0B0100F41A
        byteBuf.release();


        System.out.println(time);

    }


    /**
     * 读取ByteBuf的剩余内容并转换为16进制字符串
     *
     * @param buffer ByteBuf对象
     * @return 16进制字符串
     */
    public static String readRemainingAsHexString(ByteBuf buffer) {
        StringBuilder hexBuilder = new StringBuilder();
        int length = buffer.readableBytes(); // 获取可读字节数
        for (int i = 0; i < length; i++) {
            byte b = buffer.readByte();
            hexBuilder.append(String.format("%02X", b)); // 将字节转换为两位16进制字符串
        }
        return hexBuilder.toString();
    }


    /**
     * 将积日和积秒转换为日期时间字符串
     *
     * @param daysSince2000        相对于2000年1月1日的积日
     * @param tenthsOfMilliseconds 当天北京时的积秒（单位为0.1毫秒）
     * @return 日期时间字符串，格式为 yyyy-MM-dd HH:mm:ss.SSSS
     */
    public static String convertToDateTime(int daysSince2000, int tenthsOfMilliseconds) {
        // 计算从1970年1月1日开始的总天数
        long totalDays = daysSince2000 + DAYS_FROM_1970_TO_2000 - 1;

        // 计算总毫秒数
        long totalMilliseconds = totalDays * MILLISECONDS_PER_DAY + (tenthsOfMilliseconds);

        // 创建Calendar实例，设置时区为北京时
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

        // 设置时间
        calendar.setTimeInMillis(totalMilliseconds);

        // 格式化日期时间字符串
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
        formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
        return formatter.format(calendar.getTime());
    }


    /**
     * 从ByteBuf中读取两个4字节的数据，分别表示积日和积秒，并转换为日期时间字符串
     *
     * @param buffer 小端序的ByteBuf
     * @return 日期时间字符串，格式为 yyyy-MM-dd HH:mm:ss.SSSS
     */
    public static String convertToDateTime(ByteBuf buffer) {
        // 读取4字节的小端序数据，表示积日
        short daysSince2000 = buffer.readShortLE();

        // 读取4字节的小端序数据，表示当天的积秒（单位为0.1毫秒）
        long tenthsOfMilliseconds = buffer.readUnsignedIntLE();

        // 计算从1970年1月1日开始的总天数
        long totalDays = daysSince2000 + DAYS_FROM_1970_TO_2000 - 1;

        // 计算总毫秒数
        long totalMilliseconds = totalDays * MILLISECONDS_PER_DAY + tenthsOfMilliseconds / 10;


        // 将毫秒数转换为LocalDateTime
        LocalDateTime dateTime = LocalDateTime.ofInstant(
                java.time.Instant.ofEpochMilli(totalMilliseconds),
                ZoneId.of("Asia/Shanghai")
        );

        // 格式化日期时间字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSS").withZone(ZoneId.of("Asia/Shanghai"));
        return formatter.format(dateTime);
    }


    public static String formatTime(int daysSince2000, int tenthsOfMilliseconds) {

        // 计算从1970年1月1日开始的总天数
        long totalDays = daysSince2000 + DAYS_FROM_1970_TO_2000 - 1;

        // 计算总毫秒数
        long totalMilliseconds = totalDays * MILLISECONDS_PER_DAY + tenthsOfMilliseconds;
        // 将毫秒数转换为LocalDateTime
        LocalDateTime dateTime = LocalDateTime.ofInstant(
                java.time.Instant.ofEpochMilli(totalMilliseconds),
                ZoneId.of("UTC")
        );

        // 格式化日期时间字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("UTC"));
        return formatter.format(dateTime);
    }


    /**
     * 从ByteBuf中读取指定字节数的小端序数据，并转换为16进制字符串
     *
     * @param buffer 小端序的ByteBuf
     * @param length 要读取的字节数
     * @return 16进制字符串
     */
    public static String readLittleEndianBytesAsHex(ByteBuf buffer, int length) {
        if (length <= 0) {
            throw new IllegalArgumentException("Length must be positive");
        }

        byte[] bytes = new byte[length];
        buffer.readBytes(bytes);

        // 将字节数组转换为大端序
        reverseBytes(bytes);

        // 将字节数组转换为16进制字符串
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            hexString.append(String.format("%02X", b));
        }

        return hexString.toString();
    }

    /**
     * 反转字节数组
     *
     * @param bytes 字节数组
     */
    private static void reverseBytes(byte[] bytes) {
        for (int i = 0; i < bytes.length / 2; i++) {
            byte temp = bytes[i];
            bytes[i] = bytes[bytes.length - 1 - i];
            bytes[bytes.length - 1 - i] = temp;
        }
    }


}
